extends INodeFinder


class_name NodeFinder


## 是否在目标释放后触发目标变更事件
@export var is_check_freed: bool = false
## 是否使用缓存
@export var is_using_cache: bool = false
## 最大缓存刷新时间,0表示持久缓存
@export var max_cached_msec: int = 0


var cached_target: Node = null
var cached_msec: float = 0


func __inline_find() -> Node:
    return null

func __find_with_hook() -> Node:
    var target: Node = __inline_find()
    if target == cached_target:
        return target
    if is_check_freed:
        event_target_changed.emit(self, cached_target, target)
        if target != null:
            target.tree_exiting.connect(on_tree_exiting)
        if cached_target != null:
            cached_target.tree_exiting.disconnect(on_tree_exiting)
    cached_target = target
    return target

func on_tree_exiting() -> void:
    cached_target.tree_exiting.disconnect(on_tree_exiting)
    event_target_changed.emit(self, cached_target, null)
    cached_target = null

func find() -> Node:
    if is_using_cache:
        if not cached_target:
            return __find_with_hook()
        if max_cached_msec > 0:
            var current_msec: int = Time.get_ticks_msec()
            if current_msec > cached_msec:
                __find_with_hook()
                cached_msec = current_msec + max_cached_msec
        return cached_target
    return __find_with_hook()
